using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ABMgr : SingletonAutoMono<ABMgr>
{
    //AB包管理器，目的是让外部更方便的进行资源加载
    private AssetBundle mainAB;//主AB包
    private AssetBundleManifest manifest;//manifest.json文件
    private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
    
    //AB包存放路径
    private string pathUrl = Application.streamingAssetsPath + "/";
    
    //主包名称，根据平台自动选择名称
    private string mainABName
    {
        get
        {
            #if UNITY_IOS
                return "IOS";
            #elif UNITY_ANDROID
                return "Android";
            #elif UNITY_WEBGL
                return "WebGL";
            #else
                return "PC";
            #endif
        }
    }

    public void LoadAB(string abName)
    {
        //加载AB包
        if (mainAB == null)
        {
            mainAB = AssetBundle.LoadFromFile(pathUrl + mainABName);
            if (mainAB == null)
            {
                Debug.LogError("加载主AB包失败！");
                return ;
            }

            manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }

        //获取依赖包相关信息
        AssetBundle ab = null;
        string[] strs = manifest.GetDirectDependencies(abName);
        //加载依赖包
        foreach (string dependency in strs)
        {
            if (!abDic.ContainsKey(dependency))
            {
                ab = AssetBundle.LoadFromFile(pathUrl + dependency);
                if (ab == null)
                {
                    Debug.LogError("加载依赖包失败！");
                    return ;
                }

                abDic.Add(dependency, ab);//把依赖包加入字典
            }
        }
        
        //加载资源,如果没有加载过
        if (!abDic.ContainsKey(abName))
        {
            ab = AssetBundle.LoadFromFile(pathUrl + abName);
            abDic.Add(abName, ab);
        }
    }
    
    //同步加载AB包
    public Object LoadAssetBundleSync(string abName, string resName)
    {
        //加载AB包
        LoadAB(abName);
        //加载资源
        Object obj = abDic[abName].LoadAsset(resName);
        if (obj is GameObject)
            return Instantiate(obj);
        
        return obj;
    }
    
    //同步加载根据type指定类型（lua里面不支持泛型，所以用这种类型的方式很好）
    public Object LoadAssetBundleSync(string abName, string resName, System.Type type)
    {
        //加载AB包
        LoadAB(abName);
        //加载资源
        Object obj = abDic[abName].LoadAsset(resName, type);
        if (obj is GameObject)
            return Instantiate(obj);
        
        return obj;
    }
    
    //同步加载AB包根据泛型
    public T LoadAssetBundleSync<T>(string abName, string resName) where T : Object
    {
        //加载AB包
        LoadAB(abName);
        //加载资源
        T obj = abDic[abName].LoadAsset<T>(resName);    
        if (obj is GameObject)
            return Instantiate(obj);
        
        return obj;
    }

    //异步加载AB包
    // public void LoadAssetBundleAsync(string abName, System.Action<AssetBundle> callback)
    // {
    //     AssetBundle.LoadAssetBundleAsync(abName, (ab) =>
    //     {
    //         callback(ab);
    //     });
    // }
    
    //卸载AB包
    public void UnloadAB(string abName)
    {
        if (abDic.ContainsKey(abName))
        {
            abDic[abName].Unload(true);
            abDic.Remove(abName);
        }
    }
    
    //所有包卸载
    public void ClearAB()
    {
        AssetBundle.UnloadAllAssetBundles(true);
        abDic.Clear();
        mainAB = null;
        manifest = null;
    }
}
